package com.golden.procedure.service.impl;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.golden.procedure.client.EmployeeClientAPI;
import com.golden.procedure.clientDO.EmployeeDO;
import com.golden.procedure.dao.WorkOrderPhotographyMapper;
import com.golden.procedure.dao.WorkerAttendanceMapper;
import com.golden.procedure.dao.WorkerMapper;
import com.golden.procedure.dao.WorkerRoleMapper;
import com.golden.procedure.domain.WorkSiteSeatDO;
import com.golden.procedure.domain.WorkerDO;
import com.golden.procedure.domain.WorkerRoleDO;
import com.golden.procedure.entity.Worker;
import com.golden.procedure.entity.WorkerAttendance;
import com.golden.procedure.entity.WorkerAttendanceExample;
import com.golden.procedure.entity.WorkerExample;
import com.golden.procedure.entity.WorkerRole;
import com.golden.procedure.entity.WorkerRoleExample;
import com.golden.procedure.query.WorkerQueryDO;
import com.golden.procedure.query.WorkerRoleQueryDO;
import com.golden.procedure.result.ResultDO;
import com.golden.procedure.result.ResultSupport;
import com.golden.procedure.service.IWorkSiteSchedulingService;
import com.golden.procedure.service.IWorkSiteSeatService;
import com.golden.procedure.service.IWorkerService;
import com.golden.procedure.util.BeanUtilsExtends;
import com.golden.procedure.util.BonConstant;

@Service("workerService")
public class WorkerService extends BaseService implements IWorkerService {

	@Autowired
	EmployeeClientAPI employeeClientAPI;
	@Autowired
	IWorkSiteSchedulingService siteSchedulingService;
	@Autowired
	IWorkSiteSeatService workSiteSeatService;
	@Autowired
	WorkerMapper workerMapper;
	@Autowired
	WorkOrderPhotographyMapper workOrderPhotographyMapper;
	@Autowired
	WorkerRoleMapper workerRoleMapper;
	@Autowired
	WorkerAttendanceMapper workerAttendanceMapper;

	/**
	 * 查询员工工作日历 <b>Description:包含出勤状态、每日任务数、拍摄数等</b><br>
	 * 
	 * @param query
	 * @return ResultDO
	 * @Note <b>Author:</b> Reading.Reagan <br>
	 *       <b>Date:</b> 2018年9月19日 下午2:02:24 <br>
	 *       <b>Version:</b> 1.0
	 */
	public ResultDO workerCalendar(WorkerQueryDO query) {
		// 员工工作日历
		ResultDO result = new ResultSupport();
		// 1.数据验证
		if (isNumberInValid(query.getEmployeeID()) || StringUtils.isEmpty(query.getCalDate())) {
			result.setErrorCode(ResultDO.PARAM_ERROR);
			result.setErrorMsg("参数错误");
			result.setSuccess(false);
			return result;
		}

		// 获取日期区间
		Calendar calendar = Calendar.getInstance();
		String calDate = query.getCalDate() + "01";
		try {
			Date date = new SimpleDateFormat("yyyyMMdd").parse(calDate);
			calendar.setTime(date);
		} catch (ParseException e) {
			e.printStackTrace();
			result.setErrorCode(ResultDO.PARAM_ERROR);
			result.setErrorMsg("日期年月格式错误");
			result.setSuccess(false);
			return result;
		}
		Date startDay = calendar.getTime();
		calendar.add(Calendar.MONTH, 1);
		calendar.add(Calendar.DAY_OF_MONTH, -1);
		Date endDay = calendar.getTime();

		// 2. 查询日历
		List<WorkerDO> list = new ArrayList<WorkerDO>();

		Date schedulingDate = startDay;
		calendar = Calendar.getInstance();
		calendar.setTime(schedulingDate);
		while (schedulingDate.compareTo(endDay) <= 0) {
			WorkerDO workerDO = new WorkerDO();
			// 上门组id
			workerDO.setEmployeeID(query.getEmployeeID());
			workerDO.setSchedulingDate(schedulingDate);
			workerDO.setSchedulingDateStr(schedulingDate.getTime() + "");
			// 查询出勤状态(1-休息; 0-不休息)
			workerDO.setIsDayoff(getEmployeeStatus(schedulingDate, query.getEmployeeID()));
			// 排班状态
			if (workerDO.getIsDayoff() == BonConstant.DAYOFF_NO) {
				// 查询任务数（来自activiti）
				workerDO.setTaskNum(countActivitiTaskNum(schedulingDate, query.getEmployeeID()));
				// 查询拍摄数
				workerDO.setServiceNum(
						siteSchedulingService.countServiceNum(null, schedulingDate, query.getEmployeeID()));
			} else {
				workerDO.setDayoff("休息");
			}
			list.add(workerDO);
			calendar.add(Calendar.DAY_OF_MONTH, 1);
			schedulingDate = calendar.getTime();
		}

		result.setModel(ResultDO.FIRST_MODEL_KEY, list);
		return result;
	}

	/**
	 * 设置工位服务人员 <b>Description:</b><br>
	 * 
	 * @param domain
	 * @return ResultDO
	 * @Note <b>Author:</b> Reading.Reagan <br>
	 *       <b>Date:</b> 2018年9月20日 上午11:04:55 <br>
	 *       <b>Version:</b> 1.0
	 */
	public ResultDO setWorker(WorkerDO domain) {

		// 员工工作日历
		ResultDO result = new ResultSupport();
		// 1.数据验证
		if (isNumberInValid(domain.getEmployeeID()) || isNumberInValid(domain.getSiteSeatID())
				|| isNumberInValid(domain.getRoleID())) {
			result.setErrorCode(ResultDO.PARAM_ERROR);
			result.setErrorMsg("参数错误");
			result.setSuccess(false);
			return result;
		}

		Worker worker = new Worker();
		if (!BeanUtilsExtends.copyProperties(worker, domain)) {
			result.setErrorCode(ResultDO.SYSTEM_EXCEPTION_ERROR);
			result.setErrorMsg("数据格式转换错误");
			result.setSuccess(false);
			return result;
		}

		// 查询员工信息
		EmployeeDO employeeDO = getEmployee(domain.getEmployeeID());
		if (null == employeeDO) {
			result.setErrorCode(ResultDO.SYSTEM_EXCEPTION_ERROR);
			result.setErrorMsg("员工不存在");
			result.setSuccess(false);
			return result;
		}

		// 查询摄控日期
		WorkSiteSeatDO siteSeat = workSiteSeatService.getSiteSeatByID(domain.getSiteSeatID());
		if (null == siteSeat) {
			result.setErrorCode(ResultDO.SYSTEM_EXCEPTION_ERROR);
			result.setErrorMsg("工位分组信息查询失败");
			result.setSuccess(false);
			return result;
		}
		worker.setSchedulingDate(siteSeat.getSchedulingDate());

		// 此员工当日安排查重
		WorkerExample example = new WorkerExample();
		WorkerExample.Criteria criteria = example.createCriteria();
		criteria.andSchedulingDateEqualTo(siteSeat.getSchedulingDate());
		criteria.andEmployeeIDEqualTo(worker.getEmployeeID());
		criteria.andIsDeleteEqualTo(BonConstant.DB_NORMAL);
		criteria.andStatusEqualTo(BonConstant.WORK_STATUS_ARRANGED);
		int count = workerMapper.countByExample(example);
		if (count > 0) {
			result.setErrorCode(ResultDO.SYSTEM_EXCEPTION_ERROR);
			result.setErrorMsg("该员工今日已安排工位");
			result.setSuccess(false);
			return result;
		}

		// 查询角色
		WorkerRole role = getRole(domain.getRoleID());
		if (null == role) {
			result.setErrorCode(ResultDO.SYSTEM_EXCEPTION_ERROR);
			result.setErrorMsg("角色不存在");
			result.setSuccess(false);
			return result;
		}
		worker.setRole(role.getRole());
		worker.setRoleCode(role.getCode());

		// 删除工位改角色之前设置的人员
		example.clear();
		criteria = example.createCriteria();
		criteria.andSiteSeatIDEqualTo(domain.getSiteSeatID());
		criteria.andRoleIDEqualTo(domain.getRoleID());
		criteria.andIsDeleteEqualTo(BonConstant.DB_NORMAL);
		criteria.andStatusEqualTo(BonConstant.WORK_STATUS_ARRANGED);

		Worker entity = new Worker();
		entity.setIsDelete(BonConstant.DB_DELETE);
		entity.setAuthorID(domain.getAuthorID());
		entity.setAuthor(domain.getAuthor());
		workerMapper.updateByExampleSelective(entity, example);

		// 填充员工信息,新增服务人员数据
		worker.setEmployeeName(employeeDO.getRealName());
		worker.setOrgID(employeeDO.getOrgId());
		worker.setStatus(BonConstant.WORK_STATUS_ARRANGED);
		worker.setIsDelete(BonConstant.DB_NORMAL);
		worker.setCreatetime(Calendar.getInstance().getTime());
		worker.setAuthorID(domain.getAuthorID());
		worker.setAuthor(domain.getAuthor());

		int ret = workerMapper.insert(worker);
		if (ret < 1) {
			result.setErrorCode(ResultDO.SYSTEM_EXCEPTION_ERROR);
			result.setErrorMsg("服务人员设置失败");
			result.setSuccess(false);
			return result;
		}
		result.setModel(ResultDO.FIRST_MODEL_KEY, worker);
		return result;
	}

	/**
	 * 更换工位服务人员 <b>Description:</b><br>
	 * 
	 * @param domain
	 * @return ResultDO
	 * @Note <b>Author:</b> Reading.Reagan <br>
	 *       <b>Date:</b> 2018年9月20日 上午11:04:55 <br>
	 *       <b>Version:</b> 1.0
	 */
	public ResultDO editWorker(WorkerDO domain) {

		ResultDO result = new ResultSupport();
		// 1.数据验证
		if (isNumberInValid(domain.getEmployeeID()) || isNumberInValid(domain.getId())
				|| isNumberInValid(domain.getRoleID())) {
			result.setErrorCode(ResultDO.PARAM_ERROR);
			result.setErrorMsg("参数错误");
			result.setSuccess(false);
			return result;
		}

		Worker worker = new Worker();
		worker.setId(domain.getId());
		worker.setEmployeeID(domain.getEmployeeID());

		// 填充数据：员工信息(服务接口，测试时关闭）
		EmployeeDO employeeDO = getEmployee(domain.getEmployeeID());
		if (null == employeeDO) {
			result.setErrorCode(ResultDO.SYSTEM_EXCEPTION_ERROR);
			result.setErrorMsg("员工不存在");
			result.setSuccess(false);
			return result;
		}
		worker.setEmployeeName(employeeDO.getRealName());
		worker.setOrgID(employeeDO.getOrgId());

		worker.setModifiID(domain.getModifiID());
		worker.setModifi(domain.getModifi());

		int ret = workerMapper.updateByPrimaryKeySelective(worker);
		if (ret < 1) {
			result.setErrorCode(ResultDO.SYSTEM_EXCEPTION_ERROR);
			result.setErrorMsg("服务人员更换失败");
			result.setSuccess(false);
			return result;
		}
		result.setModel(ResultDO.FIRST_MODEL_KEY, worker);
		return result;

	}

	/**
	 * 获取员工信息 <b>Description: 获取员工信息、部门、岗位等信息</b><br>
	 * 
	 * @param employeeId
	 * @return ResultDO
	 * @Note <b>Author:</b> Reading.Reagan <br>
	 *       <b>Date:</b> 2018年9月19日 下午1:59:46 <br>
	 *       <b>Version:</b> 1.0
	 */
	public ResultDO getEmployeeById(Integer employeeID) {

		ResultDO result = new ResultSupport();
		if (isNumberInValid(employeeID)) {
			result.setErrorCode(ResultDO.PARAM_ERROR);
			result.setErrorMsg("参数错误");
			result.setSuccess(false);
			return result;
		}
		EmployeeDO employeeDO = getEmployee(employeeID);
		if (null == employeeDO) {
			result.setErrorCode(ResultDO.SYSTEM_EXCEPTION_ERROR);
			result.setErrorMsg("用户不存在");
			result.setSuccess(false);
			return result;
		}
		WorkerDO workerDO = convertWorker(employeeDO);
		result.setModel(ResultDO.FIRST_MODEL_KEY, workerDO);
		return result;
	}

	/**
	 * 查询员工信息 <b>Description:根据部门、岗位、姓名查询员工列表，可包含员工出勤及排班状态</b><br>
	 * 
	 * @param query
	 * @return ResultDO
	 * @Note <b>Author:</b> Reading.Reagan <br>
	 *       <b>Date:</b> 2018年9月19日 下午2:01:32 <br>
	 *       <b>Version:</b> 1.0
	 */
	public ResultDO queryEmployee(WorkerQueryDO query) {
		// 查询员工列表
		ResultDO result = new ResultSupport();

		String name = (StringUtils.isNotEmpty(query.getNameOrTel()) ? query.getNameOrTel() : "ALL");
		String code = (StringUtils.isNotEmpty(query.getCode()) ? query.getCode() : "ALL");
		Integer jobId = (null != query.getJobsID() ? query.getJobsID() : 0);
		List<EmployeeDO> list = employeeClientAPI.query(name, code, jobId, "all");

		List<WorkerDO> workerList = new ArrayList<WorkerDO>();

		int start = 0;
		int end = list.size();
		if (query.isPage()) {
			start = query.getStart();
			end = query.getStart() + query.getPageRows();
			result.setModel(ResultDO.SECOND_MODEL_KEY, list.size());
		}

		for (int i = start; i < end; i++) {
			if (i >= list.size()) {
				break;
			}
			WorkerDO workerDO = convertWorker(list.get(i));

			if (query.getIsNeedStatus() == BonConstant.STATUS_TRUE) {
				// 设置员工出勤、排班状态及今日任务数
				if (StringUtils.isNotEmpty(query.getSchedulingDateStr())) {
					Date schedulingDate = new Date(Long.parseLong(query.getSchedulingDateStr()));
					// 出勤状态
					workerDO.setIsDayoff(getEmployeeStatus(schedulingDate, workerDO.getEmployeeID()));
					workerDO.setDayoff("缺席");
					workerDO.setStatusName("缺席");
					if (workerDO.getIsDayoff() == BonConstant.DAYOFF_NO) {
						workerDO.setDayoff("在岗");
						// 排班状态
						workerDO.setStatus(getWorkStatus(schedulingDate, workerDO.getEmployeeID()));
						if (workerDO.getStatus() == BonConstant.WORK_STATUS_FREE) {
							workerDO.setStatusName("可排班");
						} else {
							workerDO.setStatusName("已排班");
						}
						// 今日任务数
						workerDO.setTaskNum(countActivitiTaskNum(schedulingDate, workerDO.getEmployeeID()));
					}
				}
			}

			workerList.add(workerDO);
		}
		result.setModel(ResultDO.FIRST_MODEL_KEY, workerList);
		return result;
	}

	/**
	 * 查询工位服务成员 <b>Description:根据工位分组ID查询安排的服务人员</b><br>
	 * 
	 * @param query
	 * @return ResultDO
	 * @Note <b>Author:</b> Reading.Reagan <br>
	 *       <b>Date:</b> 2018年9月19日 下午2:01:32 <br>
	 *       <b>Version:</b> 1.0
	 */
	public ResultDO queryBySiteSeat(WorkerQueryDO query) {
		// 查询工位分组服务成员
		ResultDO result = new ResultSupport();
		// 1.数据验证
		if (isNumberInValid(query.getSiteSeatID())) {
			result.setErrorCode(ResultDO.PARAM_ERROR);
			result.setErrorMsg("参数错误");
			result.setSuccess(false);
			return result;
		}

		WorkerExample example = new WorkerExample();
		WorkerExample.Criteria criteria = example.createCriteria();
		if (!isNumberInValid(query.getSiteSeatID())) {
			criteria.andSiteSeatIDEqualTo(query.getSiteSeatID());
		}
		if (!isNumberInValid(query.getRoleID())) {
			criteria.andRoleIDEqualTo(query.getRoleID());
		}
		if (StringUtils.isNotEmpty(query.getRoleCode())) {
			criteria.andRoleCodeEqualTo(query.getRoleCode());
		}
		criteria.andStatusEqualTo(BonConstant.WORK_STATUS_ARRANGED);
		criteria.andIsDeleteEqualTo(BonConstant.DB_NORMAL);
		example.setOrderByClause(" roleCode asc "); // 根据角色code排序

		List<Worker> list = workerMapper.selectByExample(example);
		List<WorkerDO> resList = getWorkerDOList(list);
		result.setModel(ResultDO.FIRST_MODEL_KEY, resList);
		return result;
	}

	/**
	 * 查询单个员工出勤状态 <b>Description:</b><br>
	 * 
	 * @param date
	 * @param employeeID
	 * @return WorkerAttendance
	 * @Note <b>Author:</b> Reading.Reagan <br>
	 *       <b>Date:</b> 2018年9月19日 上午10:39:13 <br>
	 *       <b>Version:</b> 1.0
	 */
	public Integer getEmployeeStatus(Date date, Integer employeeID) {

		WorkerAttendanceExample example = new WorkerAttendanceExample();
		WorkerAttendanceExample.Criteria criteria = example.createCriteria();
		criteria.andEmployeeIDEqualTo(employeeID);
		criteria.andSchedulingDateEqualTo(date);
		criteria.andIsDeleteEqualTo(BonConstant.DB_NORMAL);

		List<WorkerAttendance> list = workerAttendanceMapper.selectByExample(example);
		if (null != list && list.size() > 0) {
			return list.get(0).getIsDayoff();
		}
		return BonConstant.DAYOFF_NO;
	}

	/**
	 * 查询单个员工排班状态 <b>Description:</b><br>
	 * 
	 * @param date
	 * @param employeeID
	 * @return Integer 状态: 0-空闲； 1-已安排; 2-排控冲突;
	 * @Note <b>Author:</b> Reading.Reagan <br>
	 *       <b>Date:</b> 2018年9月19日 上午10:39:19 <br>
	 *       <b>Version:</b> 1.0
	 */
	public Integer getWorkStatus(Date date, Integer employeeID) {

		WorkerExample example = new WorkerExample();
		WorkerExample.Criteria criteria = example.createCriteria();
		criteria.andEmployeeIDEqualTo(employeeID);
		criteria.andSchedulingDateEqualTo(date);
		criteria.andIsDeleteEqualTo(BonConstant.DB_NORMAL);

		List<Worker> list = workerMapper.selectByExample(example);
		if (null != list && list.size() > 0) {
			return list.get(0).getStatus();
		}
		return 0;
	}

	/**
	 * 根据用户及日期查询当天的acitiviti任务数 <b>Description:</b><br>
	 * 
	 * @param date
	 * @param employeeID
	 * @return Integer
	 * @Note <b>Author:</b> Reading.Reagan <br>
	 *       <b>Date:</b> 2018年9月18日 下午5:51:15 <br>
	 *       <b>Version:</b> 1.0
	 */
	public Integer countActivitiTaskNum(Date date, Integer employeeID) {
		// 根据用户、日期查询任务数(待拍摄数量）
		Map<String, Object> params = new HashMap<String, Object>();
		// 日期
		if (null != date) {
			params.put("schedulingDate", date);
		}
		// 用户
		if (!isNumberInValid(employeeID)) {
			params.put("employeeID", employeeID);
		}
		// 拍摄状态：未拍摄
		params.put("status", Arrays.asList(new Integer[] { BonConstant.SHOT_STATUS_NORMAL }));

		return workOrderPhotographyMapper.countServiceNum(params);
	}

	@Override
	public ResultDO getWorker(Integer id) {

		ResultDO result = new ResultSupport();
		// 1.数据验证
		if (isNumberInValid(id)) {
			result.setErrorCode(ResultDO.PARAM_ERROR);
			result.setErrorMsg("参数错误");
			result.setSuccess(false);
			return result;
		}
		Worker worker = workerMapper.selectByPrimaryKey(id);
		if (worker == null) {
			result.setErrorCode(ResultDO.SYSTEM_EXCEPTION_ERROR);
			result.setErrorMsg("该成员不存在");
			result.setSuccess(false);
			return result;
		}
		WorkerDO workerDO = getWorkerDO(worker);
		result.setModel(ResultDO.FIRST_MODEL_KEY, workerDO);
		return result;
	}

	public WorkerDO convertWorker(EmployeeDO employeeDO) {
		if (null == employeeDO) {
			return null;
		}
		WorkerDO workerDO = new WorkerDO();
		workerDO.setEmployeeID(employeeDO.getId());
		workerDO.setEmployeeName(employeeDO.getRealName());
		workerDO.setOrgID(employeeDO.getOrgId());
		workerDO.setDepartment(employeeDO.getDepartment());
		workerDO.setJobsID(employeeDO.getJobsId());
		workerDO.setJobName(employeeDO.getJobName());
		workerDO.setMobile(employeeDO.getMobile());
		// TODO：等级
		workerDO.setLevel("");

		return workerDO;
	}

	@Override
	public ResultDO listRoleByWorkType(WorkerRoleQueryDO query) {
		ResultDO result = new ResultSupport();
		// 1.数据验证
		if (isNumberInValid(query.getWorkType())) {
			result.setErrorCode(ResultDO.PARAM_ERROR);
			result.setErrorMsg("参数错误");
			result.setSuccess(false);
			return result;
		}
		WorkerRoleExample example = new WorkerRoleExample();
		WorkerRoleExample.Criteria criteria = example.createCriteria();
		criteria.andWorkTypeEqualTo(query.getWorkType());
		criteria.andIsDeleteEqualTo(BonConstant.DB_NORMAL);
		example.setOrderByClause(" code asc "); // 排序

		List<WorkerRole> list = workerRoleMapper.selectByExample(example);
		List<WorkerRoleDO> doList = getWorkerRoleDOList(list);
		result.setModel(ResultDO.FIRST_MODEL_KEY, doList);
		return result;
	}

	public WorkerRole getRole(Integer id) {
		if (!isNumberInValid(id)) {
			return workerRoleMapper.selectByPrimaryKey(id);
		}
		return null;
	}

	@Override
	public ResultDO queryWorker(WorkerQueryDO queryDO) {

		ResultDO result = new ResultSupport();

		// 查询该部门下的所有子部门id
		List<Integer> orgIds = new ArrayList<Integer>();
		if (!isNumberInValid(queryDO.getOrgID())) {
			orgIds = getOrgIDs(queryDO.getOrgID());
		}

		WorkerExample example = new WorkerExample();
		WorkerExample.Criteria criteria = example.createCriteria();
		if (!isNumberInValid(queryDO.getEmployeeID())) {
			criteria.andEmployeeIDEqualTo(queryDO.getEmployeeID());
		}
		if (orgIds.size() > 0) {
			criteria.andOrgIDIn(orgIds);
		}
		if (StringUtils.isNotEmpty(queryDO.getSchedulingDateStr())) {
			criteria.andSchedulingDateEqualTo(new Date(Long.parseLong(queryDO.getSchedulingDateStr())));
		}
		criteria.andIsDeleteEqualTo(BonConstant.DB_NORMAL);
		criteria.andStatusEqualTo(BonConstant.WORK_STATUS_ARRANGED);

		example.setOrderByClause(" siteSeatID asc "); // 根据工位分组id排序
		List<Worker> list = workerMapper.selectByExample(example);

		result.setModel(ResultDO.FIRST_MODEL_KEY, getWorkerDOList(list));
		return result;
	}

	@Override
	public ResultDO delete(WorkerQueryDO queryDO) {

		ResultDO result = new ResultSupport();

		WorkerExample example = new WorkerExample();
		WorkerExample.Criteria criteria = example.createCriteria();
		if (null != queryDO.getSiteSeatIDs() && queryDO.getSiteSeatIDs().size() > 0) {
			criteria.andSiteSeatIDIn(queryDO.getSiteSeatIDs());
		}
		if (!isNumberInValid(queryDO.getSiteSeatID())) {
			criteria.andSiteSeatIDEqualTo(queryDO.getSiteSeatID());
		}
		criteria.andIsDeleteEqualTo(BonConstant.DB_NORMAL);
		Worker worker = new Worker();
		worker.setIsDelete(BonConstant.DB_DELETE);
		worker.setModifitime(Calendar.getInstance().getTime());
		workerMapper.updateByExampleSelective(worker, example);

		return result;
	}

}
